use bytes::Bytes;
use crate::error::{self, AppErr};
use super::BodyDecode;


#[derive(Debug)]
pub struct Frame {
    data: Bytes,
}

impl Frame {
    pub fn new(data: Bytes) -> Self {
        Self {
            data,
        }
    }

    pub fn ty(&self) -> u8 {
        self.data[3]
    }

    pub fn seq(&self) -> u8 {
        self.data[4]
    }

    pub fn src(&self) -> u8 {
        self.data[5]
    }

    pub fn dst(&self) -> u8 {
        self.data[6]
    }

    pub fn cmd(&self) -> u8 {
        self.data[7]
    }

    pub fn parse_cmd<'de, T: BodyDecode<'de>>(&'de self) -> Result<T, AppErr> {
        if self.data.len() < 10 {
            return Err(AppErr::Static("frame is not res"));
        }
        let mut body = &self.data[8..];
        T::decode(&mut body).ok_or(AppErr::Static("parse fail"))
    }

    pub fn poll_ack_result(&self) -> u8 {
        self.data[7]
    }

    pub fn res_ec(&self) -> u8 {
        self.data[8]
    }

    pub fn res_result(&self) -> Result<(), AppErr> {
        if self.data.len() < 11 {
            return Err(AppErr::Static("frame is not res"));
        }
        error::pase_err(self.src(), self.res_ec())
    }

    pub fn parse_res<'de, T: BodyDecode<'de>>(&'de self) -> Result<T, AppErr> {
        if self.data.len() < 11 {
            return Err(AppErr::Static("frame is not res"));
        }
        if self.res_ec() != 0 {
            return Err(error::parse_ec(self.src(), self.res_ec()))
        }
        let mut body = &self.data[9..];
        T::decode(&mut body).ok_or(AppErr::Static("parse fail"))
    }

    pub fn parse_raw<'de, T: BodyDecode<'de>>(&'de self) -> Result<T, AppErr> {
        let mut body = &self.data[7..];
        T::decode(&mut body).ok_or(AppErr::Static("parse fail"))
    }
}


